/**
 * 定义了cpp常用的各种方法，
 * 以及各个命令的具体执行方法。
*/
#include "diskutils.h"

/**
 * 打印程序标题
*/
void showTitle()
{
    cout << ".=========.\n";
    cout << "| SIMDISK |\n";
    cout << "`=========` --by FCY\n";
}

/**
 * 将目录i节点序列输出至终端
*/
void printPath(vector<folderiNode> workpath)
{
    cout << "\n@ ";
    for (auto f : workpath)
    {
        cout << f.folderName << '/';
    }
    cout << endl
         << "? ";
}

/**
 * 将目录i节点序列转换为路径字符串
*/
string getStringPath(vector<folderiNode> workpath)
{
    string s = "";
    for (auto f : workpath)
    {
        s += f.folderName;
        s += "/";
    }
    s.assign(s, 0, s.size() - 1);
    return s;
}

/**
 * 登陆终端
*/
int login()
{
    cout << "User ID(0~15): ";
    int id;
    cin >> id;
    while (id < 0 || id > 15 || cin.fail())
    {
        cout << "No such id! Input again: ";
        cin.clear();
        cin.ignore(10000, '\n');
        cin >> id;
    }
    cout << "welcome! No." << id << endl;
    return id;
}

void flushInput()
{
    string line;
    getline(cin, line);
}

/**
 * 获取共享内存，已弃用
*/
shared_mem_st *getShareMem()
{
    void *shm = NULL;
    int shmid;
    struct shared_mem_st *shared = NULL;
    //创建共享内存
    shmid = shmget((key_t)MEMKEY, sizeof(struct shared_mem_st), 0666 | IPC_CREAT);
    if (shmid == -1)
    {
        fprintf(stderr, "shmget failed\n");
        exit(EXIT_FAILURE);
    }
    //将共享内存连接到当前进程的地址空间
    shm = shmat(shmid, (void *)0, 0);
    if (shm == (void *)-1)
    {
        fprintf(stderr, "shmat failed\n");
        exit(EXIT_FAILURE);
    }
    printf("Memory attached at 0x%X\n", (long int)shm);
    //设置共享内存
    shared = (struct shared_mem_st *)shm;
    return shared;
}

/**
 * 获取空闲i节点编号
*/
int getFreeInodeNo()
{
    int i = 0;
    char c;
    while (i < INODENUM)
    {
        c = readInodeBmap(i);
        //cout<<c;
        if (c == '1')
        {
            i++;
            continue;
        }
        else
        {
            //cout<<endl;
            return i;
        }
    }
    cout << '[' << __FUNCTION__ << ']';
    cout << err_nofreeinode;
    return -1;
}

/**
 * 获取空闲文件块编号
*/
int getFreeBlkNo()
{
    //TODO
    int i = 0;
    char c;
    while (i < BLKNUM)
    {
        c = readFblkBmap(i);
        //cout<<c;
        if (c == '1')
        {
            i++;
            continue;
        }
        else
        {
            //cout<<endl;
            return i;
        }
    }
    cout << '[' << __FUNCTION__ << ']';
    cout << err_nofreeblk;
    return -1;
}

/**
 * 分割字符串
*/
void SplitString(const string &s, vector<string> &v, const string &c)
{
    string::size_type pos1, pos2;
    pos2 = s.find(c);
    pos1 = 0;
    while (string::npos != pos2)
    {
        v.push_back(s.substr(pos1, pos2 - pos1));

        pos1 = pos2 + c.size();
        pos2 = s.find(c, pos1);
    }
    if (pos1 != s.length())
        v.push_back(s.substr(pos1));
}

/**
 * 显示文件信息
*/
void showFile(int nodePos)
{
    if (nodePos >= FOLDERSIGN)
    {
        cout << err_notafile;
        return;
    }
    fileiNode file = readFileInode(nodePos);
    for (int i = 0; i < file.fileSize; ++i)
    {
        int baddr = file.blockAddr[i];
        char *blk = new char[1024]{};
        getBlock(blk, (baddr + BLKSTART));
        cout << blk;
    }
    cout << endl;
}

/**
 * 检查是否有权限修改
*/
bool chechPermission(char code, int id)
{
    int cint = castChar2Int(code);
    int cid = cint >> 4;
    bool canAlter = readBitInChar(code, 8);
    if (cid == id || canAlter)
    {
        return true;
    }
    return false;
}

/**
 * 通过路径字符串获得目录i节点
*/
bool getFolderByPath(folderiNode &f, string path)
{
    vector<string> pathv;
    SplitString(path, pathv, "/");
    if (pathv[0] != "root")
    {
        cout << err_path;
        return false;
    }
    f = readFolderInode(0);
    bool find;
    for (string s : pathv)
    {
        if (s == "root")
            continue;
        //沿路径查找
        find = false;
        FolderItem item;
        for (int i = 0; i < f.folderSize; ++i)
        {
            item = f.subItems[i];
            if (item.name == s)
            { //找到同名节点
                find = true;
                break;
            }
        }
        if (find)
        {
            if (item.nodeNo < FOLDERSIGN)
            { //不是目录
                cout << err_notafolder;
                return false;
            }
            f = readFolderInode(item.nodeNo - FOLDERSIGN);
        }
        else
        {
            cout << err_foldernf;
            return false;
        }
    }
    return true;
}

/**
 * 通过路径字符串，
 * 获取从根目录到文件夹的整个路径i节点
*/
bool getFolderByPath(vector<folderiNode> &wp, string path)
{
    vector<string> pathv;
    SplitString(path, pathv, "/");
    if (pathv[0] != "root")
    {
        cout << err_path;
        return false;
    }
    folderiNode f;
    f = readFolderInode(0);
    wp.clear();
    wp.push_back(f);
    bool find;
    for (string s : pathv)
    {
        if (s == "root")
            continue;
        //沿路径查找
        find = false;
        FolderItem item;
        for (int i = 0; i < f.folderSize; ++i)
        {
            item = f.subItems[i];
            if (item.name == s)
            { //找到同名节点
                find = true;
                break;
            }
        }
        if (find)
        {
            if (item.nodeNo < FOLDERSIGN)
            { //不是目录
                cout << err_notafolder;
                return false;
            }
            f = readFolderInode(item.nodeNo - FOLDERSIGN);
            wp.push_back(f);
        }
        else
        {
            cout << err_foldernf;
            return false;
        }
    }
    return true;
}

/**
 * 执行dir命令时调用的显示目录内容函数
*/
void showFolder(folderiNode now)
{
    FolderItem item;
    fileiNode file;
    folderiNode folder;
    cout << "protect  createtime        node size addr   name\n";
    for (int i = 0; i < now.folderSize; ++i)
    {
        item = now.subItems[i];
        if (item.nodeNo < FOLDERSIGN)
        {
            file = readFileInode(item.nodeNo);
            cout << castChar2Bin(file.protectCode) << " ";
            cout << timeToString(file.createTime) << " ";
            cout << setw(5) << left << item.nodeNo;
            cout << setw(5) << left << (int)file.fileSize;
            cout << setw(7) << left << (file.nodeNo + INODESTART) * KB;
            cout << item.name << endl;
        }
        else
        {
            folder = readFolderInode(item.nodeNo - FOLDERSIGN);
            cout << castChar2Bin(folder.protectCode) << " ";
            cout << timeToString(folder.createTime) << " ";
            cout << setw(5) << left << item.nodeNo - FOLDERSIGN;
            cout << setw(5) << left << (int)folder.folderSize;
            cout << setw(7) << left << (folder.nodeNo - FOLDERSIGN + INODESTART) * KB;
            cout << '/' << item.name << endl;
        }
    }
}

/**
 * 执行dir /s命令时的递归调用函数
*/
void showFolder_s(folderiNode now, int depth)
{
    FolderItem item;
    fileiNode file;
    folderiNode folder;
    for (int i = 0; i < now.folderSize; ++i)
    {
        item = now.subItems[i];
        if (item.nodeNo < FOLDERSIGN)
        {
            file = readFileInode(item.nodeNo);
            for (int ii = 0; ii < depth; ++ii)
                cout << "    ";
            cout << item.name << endl;
        }
        else
        {
            folder = readFolderInode(item.nodeNo - FOLDERSIGN);
            for (int ii = 0; ii < depth; ++ii)
                cout << "    ";
            cout << '/' << item.name << endl;
            if (folder.folderSize > 0)
            {
                for (int ii = 0; ii < depth; ++ii)
                    cout << "    ";
                cout << " \\__" << endl;
                showFolder_s(folder, depth + 1);
            }
        }
    }
}

/**
 * 通过路径寻找文件
*/
bool getFileByPath(folderiNode now, fileiNode &file, string path)
{
    vector<string> pathv;
    SplitString(path, pathv, "/");
    FolderItem item;
    if (pathv[0] == "root")
        now = readFolderInode(0);
    for (string s : pathv)
    {
        //root节点跳过
        if (s == "root")
            continue;
        //最后一个节点，找文件
        if (s == pathv.back())
        {
            for (int i = 0; i < now.folderSize; ++i)
            {
                item = now.subItems[i];
                if (item.name == s)
                { //找到同名节点
                    if (item.nodeNo < FOLDERSIGN)
                    {
                        file = readFileInode(item.nodeNo);
                        return true;
                    }
                    else
                    {
                        cout << err_notafile;
                        return false;
                    }
                }
            }
            cout << err_filenf;
            return false;
        }
        //沿路径查找
        bool find = false;
        for (int i = 0; i < now.folderSize; ++i)
        {
            item = now.subItems[i];
            if (item.name == s)
            { //找到同名节点
                find = true;
                break;
            }
        }
        if (find)
        {
            if (item.nodeNo < FOLDERSIGN)
            { //不是目录
                cout << err_foldernf;
                return false;
            }
            now = readFolderInode(item.nodeNo - FOLDERSIGN);
        }
        else
        {
            cout << err_foldernf;
            return false;
        }
    }
    cout << err_filenf;
    return false;
    /*if (pathv[0] != "root")
    { //在当前工作，目录寻找

        for (int i = 0; i < now.folderSize; ++i)
        {
            item = now.subItems[i];
            if (item.name == pathv.back())
            { //找到同名节点
                if (item.nodeNo < FOLDERSIGN)
                {
                    file = readFileInode(item.nodeNo);
                    return true;
                }
                else
                {
                    cout << err_notafile;
                    return false;
                }
            }
        }
        cout << err_filenf;
        return false;
    }
    else
    { //pathv[0]=="root"
        now = readFolderInode(0);
    }*/
}

/**
 * check命令的递归调用函数
*/
void checkHelper(folderiNode now, map<int, int> *inodemap, map<int, int> *blockmap)
{
    FolderItem item;
    fileiNode file;
    folderiNode folder;
    for (int i = 0; i < now.folderSize; ++i)
    {
        item = now.subItems[i];
        if (item.nodeNo < FOLDERSIGN) // a file inode
        {
            file = readFileInode(item.nodeNo);
            //deal with inode
            if (inodemap->count(file.nodeNo)) // file inode used again
            {
                int oldno = file.nodeNo;
                int freeno = getFreeInodeNo();
                file.nodeNo = freeno;
                writeFileInode(file, freeno);
                writeInodeBmap(freeno, 1);
                now.subItems[i].nodeNo = freeno;
                writeFolderInode(now, now.nodeNo - FOLDERSIGN);
                cout << "correct file inode error at: " << oldno << endl;
            }
            else
                inodemap->insert(pair<int, int>(file.nodeNo, 1));
            //deal with fileblock
            for (int j = 0; j < file.fileSize; ++j)
            {
                if (blockmap->count(file.blockAddr[j])) //fileblock used again
                {
                    int oldno = file.blockAddr[j];
                    int freeno = getFreeBlkNo();
                    char *buff = new char[KB]{};
                    getBlock(buff, oldno);
                    saveBlock(buff, freeno);
                    file.blockAddr[j] = freeno;
                    writeFileInode(file, file.nodeNo);
                    cout << "correct fileblock error at: " << oldno << endl;
                }
                else
                    blockmap->insert(pair<int, int>(file.blockAddr[j], 1));
            }
        }
        else // a folder inode
        {
            int no = item.nodeNo - FOLDERSIGN;
            folder = readFolderInode(no);
            //deal with inode
            if (inodemap->count(no)) // folder inode used again
            {
                int freeno = getFreeInodeNo();
                folder.nodeNo = freeno + FOLDERSIGN;
                writeFolderInode(folder, freeno);
                writeInodeBmap(freeno, 1);
                now.subItems[i].nodeNo = freeno;
                writeFolderInode(now, now.nodeNo - FOLDERSIGN);
                cout << "correct folder inode error at: " << no << endl;
            }
            else
                inodemap->insert(pair<int, int>(no, 1));
            //go deeper
            if (folder.folderSize > 0)
                checkHelper(folder, inodemap, blockmap);
        }
    }
}

/**
 * 执行check命令
*/
void doCheck(vector<string> cmdv, vector<folderiNode> &workpath, int userid)
{
    if (cmdv.size() > 1)
    {
        cout << usage_check;
        cout << err_toomuchpara;
        return;
    }
    map<int, int> inodemap, blockmap;
    folderiNode root = readFolderInode(0);
    checkHelper(root, &inodemap, &blockmap);
    map<int, int>::iterator iter;
    if (DEBUG)
    {
        cout << '[' << __FUNCTION__ << ']';
        cout << "inodemap:" << endl;
        for (iter = inodemap.begin(); iter != inodemap.end(); iter++)
        {
            cout << iter->first << ":" << iter->second << ":" << readInodeBmap(iter->first) << endl;
        }
        cout << "blockmap:" << endl;
        for (iter = blockmap.begin(); iter != blockmap.end(); iter++)
        {
            cout << iter->first << ":" << iter->second << ":" << readFblkBmap(iter->first) << endl;
        }
    }
}

/**
 * 执行copy命令
*/
void doCopy(vector<string> cmdv, vector<folderiNode> &workpath, int userid)
{
    if (cmdv.size() != 3)
    {
        cout << usage_copy;
        return;
    }
    string spath = cmdv[1];
    string dpath = cmdv[2];
    if (spath == "-h")
    {
        cout << usage_copy;
        return;
    }
    //寻找目的目录
    folderiNode now;
    if (!getFolderByPath(now, dpath))
    {
        return;
    }
    if (spath.size() > 6)
    {
        string sign = spath.substr(0, 6);
        //cout << sign << endl;
        //copy <host>/home/chengyu/TGG.txt root/fcy/
        if (sign == "<host>") //从宿主机复制文件
        {
            spath = spath.substr(6);
            //打开文件
            ifstream source(spath, ios::binary | ios::in);
            if (source.fail())
            {
                cout << err_filenf;
                return;
            }
            //大小
            source.seekg(0, ios::end);
            int size = source.tellg() % 1024 > 0 ? 1 : 0;
            size += source.tellg() / 1024;
            if (size > 252)
            {
                cout << err_ftoobig;
                return;
            }
            //文件名
            vector<string> spathv;
            SplitString(spath, spathv, "/");
            string name = spathv.back();
            if (name.size() > 28)
            {
                cout << usage_copy;
                return;
            }
            //建立i节点
            fileiNode file;
            int freeid;
            if (freeid = getFreeInodeNo())
                file.nodeNo = freeid;
            else
                return;
            file.fileSize = 0;
            file.protectCode = (char)((userid << 4) + 14);
            file.createTime = getIntTime();
            file.lastCatTime = 0;
            //更新目录节点
            if (!now.addSubItem(file.nodeNo, name))
                return;
            if (workpath.back().nodeNo == now.nodeNo)
                workpath.back() = now;
            //复制
            int freeblk;
            char *buff;
            source.seekg(0);
            for (int i = 0; i < size; ++i)
            {
                if (freeblk = getFreeBlkNo())
                {
                    buff = new char[KB]{};
                    source.read(buff, KB);
                    file.addBlock(freeblk);
                    saveBlock(buff, freeblk + BLKSTART);
                    writeFblkBmap(freeblk, 1);
                    delete (buff);
                }
                else
                {
                    break;
                }
            }
            cout << file.toString(1);
            //存储新节点、新的工作目录节点
            writeFileInode(file, file.nodeNo);
            writeFolderInode(now, now.nodeNo - FOLDERSIGN);
        }
        //copy root/TGG2.txt root/fcy/
        else //从simdisk复制文件 TODO
        {
            //寻找源文件
            fileiNode source;
            if (!getFileByPath(workpath.back(), source, spath))
                return;
            //文件名
            vector<string> spathv;
            SplitString(spath, spathv, "/");
            string name = spathv.back();
            //建立i节点
            fileiNode file;
            int freeid;
            if (freeid = getFreeInodeNo())
                file.nodeNo = freeid;
            else
                return;
            file.fileSize = 0;
            file.protectCode = (char)((userid << 4) + 14);
            file.createTime = getIntTime();
            file.lastCatTime = 0;
            //复制 TODO
            int freeblk;
            char *buff;
            int size = castChar2Int(source.fileSize);
            for (int i = 0; i < size; ++i)
            {
                if (freeblk = getFreeBlkNo())
                {
                    buff = new char[KB]{};
                    getBlock(buff, source.blockAddr[i] + BLKSTART);
                    file.addBlock(freeblk);
                    saveBlock(buff, freeblk + BLKSTART);
                    writeFblkBmap(freeblk, 1);
                    delete (buff);
                }
                else
                {
                    break;
                }
            }
            cout << file.toString(1);
            //更新目录节点
            if (!now.addSubItem(file.nodeNo, name))
                return;
            if (workpath.back().nodeNo == now.nodeNo)
                workpath.back() = now;
            //存储新节点、新的工作目录节点
            writeFileInode(file, file.nodeNo);
            writeFolderInode(now, now.nodeNo - FOLDERSIGN);
        }
    }
}

/**
 * 执行cd命令
*/
void doCd(vector<string> cmdv, vector<folderiNode> &workpath, int userid)
{
    if (cmdv.size() != 2)
    {
        cout << usage_cd;
        return;
    }
    string name = cmdv[1];
    //返回上级目录
    if (name == "..")
    {
        if (workpath.size() > 1)
        {
            workpath.pop_back();
            workpath.back() = readFolderInode(workpath.back().nodeNo - FOLDERSIGN);
        }
        else
        {
            cout << err_returnfromroot;
        }
        return;
    }
    //进入子目录
    if (name.size() > 28 || name == "-h")
    {
        cout << usage_cd;
        return;
    }
    folderiNode now = workpath.back();
    FolderItem item;
    for (int i = 0; i < now.folderSize; ++i)
    {
        item = now.subItems[i];
        if (item.name == name)
        {
            if (item.nodeNo < FOLDERSIGN)
            {
                cout << err_notafolder;
                return;
            }
            folderiNode folder = readFolderInode(item.nodeNo - FOLDERSIGN);
            workpath.push_back(folder);
            return;
        }
    }
    cout << err_foldernf;
}

/**
 * 执行cat命令
*/
void doCat(vector<string> cmdv, vector<folderiNode> &workpath, int userid)
{
    if (cmdv.size() != 2)
    {
        cout << usage_cat;
        return;
    }
    string name = cmdv[1];
    if (name.size() > 28 || name == "-h")
    {
        cout << usage_cat;
        return;
    }
    folderiNode now = workpath.back();
    FolderItem item;
    for (int i = 0; i < now.folderSize; ++i)
    {
        item = now.subItems[i];
        if (item.name == name)
        {
            cout << "<" << name << ">" << endl;
            showFile(item.nodeNo);
            return;
        }
    }
    cout << err_filenf;
}

/**
 * 执行dir命令
*/
void doDir(vector<string> cmdv, vector<folderiNode> &workpath, int userid)
{
    folderiNode now = workpath.back();
    if (now.folderSize == 0)
    {
        cout << err_nothing;
        return;
    }
    if (cmdv.size() == 2 && cmdv[1] == "/s")
    { //递归显示
        showFolder_s(now, 0);
        return;
    }
    showFolder(now);
}

/**
 * 执行newfile命令
*/
void doNewfile(vector<string> cmdv, vector<folderiNode> &workpath, int userid)
{
    if (cmdv.size() != 2)
    {
        cout << usage_newfile;
        return;
    }
    string name = cmdv[1];
    if (name.size() > 28 || name == "-h")
    {
        cout << usage_newfile;
        return;
    }
    folderiNode now = workpath.back();
    //建立新文件节点
    fileiNode file;
    int freeid;
    if (freeid = getFreeInodeNo())
    {
        file.nodeNo = freeid;
    }
    else
    {
        return;
    }
    file.fileSize = 0;
    file.protectCode = (char)((userid << 4) + 14); //所有用户均可读，创建者可改
    file.createTime = getIntTime();                //获取当前时间
    file.lastCatTime = 0;                          //从未打开，故为0
    cout << file.toString();
    //更新工作目录节点
    now.addSubItem(file.nodeNo, name);
    workpath.back() = now;
    //存储新节点、新的工作目录节点
    writeFileInode(file, file.nodeNo);
    writeFolderInode(now, now.nodeNo - FOLDERSIGN);
}

/**
 * 执行md命令
*/
void doMd(vector<string> cmdv, vector<folderiNode> &workpath, int userid)
{
    if (cmdv.size() != 2)
    {
        cout << usage_md;
        return;
    }
    string name = cmdv[1];
    if (name.size() > 28 || name == "-h")
    {
        cout << usage_md;
        return;
    }
    folderiNode now = workpath.back();
    //建立新目录节点
    folderiNode fi;
    int freeid;
    if (freeid = getFreeInodeNo())
    {
        fi.nodeNo = freeid + FOLDERSIGN;
        //cout << "free inode id:" << freeid << endl;
    }
    else
    {
        return;
    }
    strcpy(fi.folderName, name.c_str());
    fi.folderSize = 0;
    fi.protectCode = (char)((userid << 4) + 14); //默认所有用户均可读，创建者可改
    fi.createTime = getIntTime();                //获取当前时间
    fi.lastCatTime = 0;                          //从未打开，故为0
    cout << fi.toString();
    //更新工作目录节点
    now.addSubItem(fi.nodeNo, name);
    workpath.back() = now;
    //存储新节点、新的工作目录节点
    writeFolderInode(fi, fi.getPos());
    writeFolderInode(now, now.nodeNo - FOLDERSIGN);
}

/**
 * 执行rd命令
*/
void doRd(vector<string> cmdv, vector<folderiNode> &workpath, int userid)
{
    if (cmdv.size() != 2)
    {
        cout << usage_rd;
        return;
    }
    string name = cmdv[1];
    if (name.size() > 28 || name == "-h")
    {
        cout << usage_rd;
        return;
    }
    folderiNode now = workpath.back();
    FolderItem item;
    for (int i = 0; i < now.folderSize; ++i)
    {
        item = now.subItems[i];
        if (item.name == name)
        {
            //检查是否为目录
            if (item.nodeNo < FOLDERSIGN)
            {
                cout << err_notafolder;
                return;
            }
            folderiNode folder = readFolderInode(item.nodeNo - FOLDERSIGN);
            //检查修改权限
            if (!chechPermission(folder.protectCode, userid))
            {
                cout << err_pmsdeny;
                return;
            }
            //文件夹非空，删前确认
            if (folder.folderSize > 0)
            {
                string s;
                cout << "All files in this folder will be removed!\n";
                cout << "confirm?(y/n)";
                cin >> s;
                flushInput();
                if (s == "n")
                {
                    return;
                }
            }
            //删除相应目录节点
            writeInodeBmap(item.nodeNo - FOLDERSIGN, 0);
            //更新当前目录节点
            int size = castChar2Int(now.folderSize) - 1;
            now.folderSize = (char)size;
            for (int ii = i; ii < now.folderSize; ++ii)
            {
                now.subItems[ii] = now.subItems[ii + 1];
            }
            //保存当前目录
            writeFolderInode(now, now.nodeNo - FOLDERSIGN);
            //更新工作目录
            workpath.back() = now;
            return;
        }
    }
    cout << err_foldernf;
}

/**
 * 执行del命令
*/
void doDel(vector<string> cmdv, vector<folderiNode> &workpath, int userid)
{
    if (cmdv.size() != 2)
    {
        cout << usage_del;
        return;
    }
    string name = cmdv[1];
    if (name.size() > 28 || name == "-h")
    {
        cout << usage_del;
        return;
    }
    folderiNode now = workpath.back();
    FolderItem item;
    for (int i = 0; i < now.folderSize; ++i)
    {
        item = now.subItems[i];
        if (item.name == name)
        {
            //检查是否为文件
            if (item.nodeNo > FOLDERSIGN)
            {
                cout << err_notafile;
                return;
            }
            //检查修改权限
            fileiNode file = readFileInode(item.nodeNo);
            if (!chechPermission(file.protectCode, userid))
            {
                cout << err_pmsdeny;
                return;
            }
            //释放占用的块
            for (int j = 0; j < castChar2Int(file.fileSize); ++j)
            {
                int pos = file.blockAddr[j];
                writeFblkBmap(pos, 0);
            }
            //删除相应文件节点
            writeInodeBmap(item.nodeNo, 0);
            //更新当前目录节点
            int size = castChar2Int(now.folderSize) - 1;
            now.folderSize = (char)size;
            for (int ii = i; ii < now.folderSize; ++ii)
            {
                now.subItems[ii] = now.subItems[ii + 1];
            }
            //保存当前目录
            writeFolderInode(now, now.nodeNo - FOLDERSIGN);
            //更新工作目录
            workpath.back() = now;
            return;
        }
    }
    cout << err_filenf;
}

/**
 * 执行format命令
*/
void doFormat(vector<string> cmdv, vector<folderiNode> &workpath, int userid)
{
    string s;
    cout << "All files on disk will be removed!\n";
    cout << "confirm?(y/n)";
    cin >> s;
    if (s == "y")
    {
        formatDisk();
        flushInput();
        loadBitMap();
        userid = login();
        workpath.clear();
        workpath.push_back(readFolderInode(0));
    }
    flushInput();
}